home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
muds
/
pennmush.000
/
pennmush-1.50-p8-linux.tar
/
pennmush
/
boolexp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-05
|
9KB
|
411 lines
/* boolexp.c */
#include "copyright.h"
#include <ctype.h>
#include <string.h>
#include "db.h"
#include "match.h"
#include "externs.h"
#include "config.h"
#include "interface.h"
int check_attrib_lock();
int eval_boolexp(player, b, privs, nrecurs, locktype)
dbref player;
struct boolexp *b;
dbref privs;
int nrecurs;
int locktype;
{
ATTR *a;
char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN];
if(player < 0 || player >= db_top)
return 0;
if (nrecurs > MAX_DEPTH) {
notify(player,"Sorry, broken lock!");
return 0;
}
if (b == TRUE_BOOLEXP) {
return 1;
} else {
switch (b->type) {
case BOOLEXP_IND:
if(b->sub1->type != BOOLEXP_CONST)
return 0;
nrecurs++;
switch (locktype) {
case BASICLOCK:
return (eval_boolexp(player, db[b->sub1->thing].key, privs, nrecurs,
locktype));
break;
case USELOCK:
return (eval_boolexp(player, db[b->sub1->thing].usekey, privs,
nrecurs, locktype));
break;
case ENTERLOCK:
return (eval_boolexp(player, db[b->sub1->thing].enterkey, privs,
nrecurs, locktype));
break;
default:
/* should never be reached */
notify(player, "Broken lock!");
do_log(LT_ERR, 0, 0, "Bad lock type %d on object #%d",
locktype, b->thing);
return 0;
} break;
case BOOLEXP_AND:
return (eval_boolexp(player, b->sub1, privs, nrecurs, locktype)
&& eval_boolexp(player, b->sub2, privs, nrecurs, locktype));
case BOOLEXP_OR:
return (eval_boolexp(player, b->sub1, privs, nrecurs, locktype)
|| eval_boolexp(player, b->sub2, privs, nrecurs, locktype));
case BOOLEXP_NOT:
return !eval_boolexp(player, b->sub1, privs, nrecurs, locktype);
case BOOLEXP_CONST:
return (b->thing == player
|| member(b->thing, db[player].contents));
case BOOLEXP_IS:
return (b->sub1->thing == player);
case BOOLEXP_CARRY:
return (member(b->sub1->thing,db[player].contents));
case BOOLEXP_OWNER:
return (Owner(b->sub1->thing) == Owner(player));
case BOOLEXP_ATR:
a = atr_complete_match(player, b->atr_lock->name, privs);
if(!a)
return 0;
strcpy(tbuf1, uncompress(b->atr_lock->text));
strcpy(tbuf2, uncompress(a->value));
return (int) local_wild_match(tbuf1, tbuf2);
case BOOLEXP_EVAL:
strcpy(tbuf1, uncompress(b->atr_lock->text));
return (int) check_attrib_lock(player, privs, b->atr_lock->name,
tbuf1);
default:
do_log(LT_ERR, 0, 0, "Bad boolexp type %d in object #%d",
b->type, b->thing);
report();
return 0;
} /* switch */
/* should never be reached */
do_log(LT_ERR, 0, 0, "Broken lock type %d in object called by #%d",
locktype, player);
return 0;
} /* else */
}
/* If the parser returns TRUE_BOOLEXP, you lose */
/* TRUE_BOOLEXP cannot be typed in by the user; use @unlock instead */
static const char *parsebuf;
static dbref parse_player;
static void skip_whitespace()
{
while (*parsebuf && isspace(*parsebuf))
parsebuf++;
}
static struct boolexp *parse_boolexp_E(); /* defined below */
static struct boolexp *test_atr(s, c)
char *s;
char c;
{
struct boolexp *b;
char tbuf1[BUFFER_LEN];
strcpy(tbuf1, s);
for (s = tbuf1; *s && (*s != c); s++) ;
if (!*s)
return (0);
*s++ = 0;
if (strlen(tbuf1) == 0)
return (0);
b = alloc_bool();
if (c == ':')
b->type = BOOLEXP_ATR;
else
b->type = BOOLEXP_EVAL;
/* !!! Possible portability problem!!!!! */
b->atr_lock = alloc_atr(tbuf1, s);
return (b);
}
/* L -> (E); L -> object identifier */
static struct boolexp *parse_boolexp_L()
{
struct boolexp *b;
char *p;
char tbuf1[BUFFER_LEN];
skip_whitespace();
switch (*parsebuf) {
case '(':
parsebuf++;
b = parse_boolexp_E();
skip_whitespace();
if (b == TRUE_BOOLEXP || *parsebuf++ != ')') {
free_boolexp(b);
return TRUE_BOOLEXP;
} else {
return b;
}
/* break; */
default:
/* must have hit an object ref */
/* load the name into our buffer */
p = tbuf1;
while (*parsebuf
&& *parsebuf != AND_TOKEN
&& *parsebuf != OR_TOKEN
&& *parsebuf != ')') {
*p++ = *parsebuf++;
}
/* strip trailing whitespace */
*p-- = '\0';
while (isspace(*p))
*p-- = '\0';
/* check for an attribute */
b = test_atr(tbuf1, ':');
if (b)
return (b);
/* check for an eval */
b = test_atr(tbuf1, '/');
if (b)
return b;
b = alloc_bool();
b->type = BOOLEXP_CONST;
/* do the match */
init_match(parse_player, tbuf1, TYPE_THING);
match_neighbor();
match_possession();
match_me();
match_absolute();
match_player();
b->thing = match_result();
if (b->thing == NOTHING) {
notify(parse_player,
tprintf("I don't see %s here.", tbuf1));
free_bool(b);
return TRUE_BOOLEXP;
} else if (b->thing == AMBIGUOUS) {
notify(parse_player,
tprintf("I don't know which %s you mean!", tbuf1));
free_bool(b);
return TRUE_BOOLEXP;
} else {
return b;
}
/* break */
}
}
/* O -> $Identifier ; O -> L */
static struct boolexp *parse_boolexp_O()
{
struct boolexp *b2;
skip_whitespace();
if (*parsebuf == OWNER_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_OWNER;
if (((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
(b2->sub1->type != BOOLEXP_CONST)) {
free_boolexp(b2);
return(TRUE_BOOLEXP);
} else
return (b2);
}
return (parse_boolexp_L());
}
/* C -> +Identifier ; C -> O */
static struct boolexp *parse_boolexp_C()
{
struct boolexp *b2;
skip_whitespace();
if(*parsebuf == IN_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_CARRY;
if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
(b2->sub1->type != BOOLEXP_CONST)) {
free_boolexp(b2);
return(TRUE_BOOLEXP);
} else
return(b2);
}
return (parse_boolexp_O());
}
/* I -> =Identifier ; I -> C */
static struct boolexp *parse_boolexp_I()
{
struct boolexp *b2;
skip_whitespace();
if(*parsebuf == IS_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_IS;
if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
(b2->sub1->type != BOOLEXP_CONST)){
free_boolexp(b2);
return(TRUE_BOOLEXP);
} else
return(b2);
}
return(parse_boolexp_C());
}
/* A -> @L; A -> I */
static struct boolexp *parse_boolexp_A()
{
struct boolexp *b2;
skip_whitespace();
if(*parsebuf == AT_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_IND;
if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
(b2->sub1->type != BOOLEXP_CONST)) {
free_boolexp(b2);
return(TRUE_BOOLEXP);
} else
return (b2);
}
return(parse_boolexp_I());
}
/* F -> !F;F -> A */
static struct boolexp *parse_boolexp_F()
{
struct boolexp *b2;
skip_whitespace();
if (*parsebuf == NOT_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_NOT;
if ((b2->sub1 = parse_boolexp_F()) == TRUE_BOOLEXP) {
free_boolexp(b2);
return (TRUE_BOOLEXP);
} else
return (b2);
}
return (parse_boolexp_A());
}
/* T -> F; T -> F & T */
static struct boolexp *parse_boolexp_T()
{
struct boolexp *b;
struct boolexp *b2;
if ((b = parse_boolexp_F()) == TRUE_BOOLEXP) {
return b;
} else {
skip_whitespace();
if (*parsebuf == AND_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_AND;
b2->sub1 = b;
if ((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) {
free_boolexp(b2);
return TRUE_BOOLEXP;
} else {
return b2;
}
} else {
return b;
}
}
}
/* E -> T; E -> T | E */
static struct boolexp *parse_boolexp_E()
{
struct boolexp *b;
struct boolexp *b2;
if ((b = parse_boolexp_T()) == TRUE_BOOLEXP) {
return b;
} else {
skip_whitespace();
if (*parsebuf == OR_TOKEN) {
parsebuf++;
b2 = alloc_bool();
b2->type = BOOLEXP_OR;
b2->sub1 = b;
if ((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) {
free_boolexp(b2);
return TRUE_BOOLEXP;
} else {
return b2;
}
} else {
return b;
}
}
}
struct boolexp *parse_boolexp(player, buf)
dbref player;
const char *buf;
{
parsebuf = buf;
parse_player = player;
return parse_boolexp_E();
}
int check_attrib_lock(player, target, atrname, str)
dbref player;
dbref target;
const char *atrname;
const char *str;
{
/* player is attempting to pass the lock on target, which has
* an attribute lock of the form "atrname/value".
* This lock is passed if the equivalent of the MUSH function
* get_eval(target/atrname) is value. This does NOT do a wildcard
* match. It is also case-sensitive for matching.
*/
ATTR *a;
char *buff = NULL;
int match = 0;
char tbuf1[BUFFER_LEN];
if (!atrname || !*atrname || !str || !*str)
return 0;
/* fail if there's no matching attribute */
a = atr_get(target, strupper(atrname));
if (!a || (strlen(uncompress(a->value)) > BUFFER_LEN))
return 0;
strcpy(tbuf1, uncompress(a->value));
/* perform pronoun substitution */
buff = exec(target, player, EV_STRIP | EV_FCHECK, tbuf1);
if (!strcmp(buff, str))
match = 1;
if (buff)
free(buff);
return match;
}